﻿using System.Dynamic;
using System.Globalization;
using MicrosoftJsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;

namespace Ly.EBussiness.Common.DapperUtils.Page
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class QueryBase
    {
        /// <summary>
        /// where 条件集合
        /// </summary>
        [MicrosoftJsonIgnore]
        protected List<QueryWhereInfo> Wheres { get; set; } = new List<QueryWhereInfo>();

        /// <summary>
        /// 排序方式
        /// </summary>
        protected List<string> Sorts = new();

        /// <summary>
        /// 条件，排序 初始化标记
        /// </summary>
        private bool _isResolveCondition;

        /// <summary>
        /// 提供核心查询sql  不要自行拼接 where 和sort
        /// 形如： SELECT …… FROM ……
        /// </summary>
        /// <returns></returns>
        public abstract string GetSelectSql();

        /// <summary>
        /// 解析条件
        /// </summary>
        protected abstract void ResolveCondition();

        /// <summary>
        /// 处理排序
        /// </summary>
        protected abstract void ResolveSort();

        /// <summary>
        /// 新增格式化条件
        /// </summary>
        /// <param name="whereString"></param>
        /// <param name="whereName"></param>
        /// <param name="whereValue"></param>
        protected void AddWhere(string whereString, string whereName, object whereValue)
        {
            if (!string.IsNullOrWhiteSpace(whereName) && Wheres.Any(w => w.WhereParamName.Equals(whereName)))
                throw new Exception($"{whereName} 条件已存在,若要重复利用此查询条件,请直接使用 AddWhere(string whereString) 方法");
            Wheres.Add(new QueryWhereInfo
            {
                WhereParamName = whereName,
                WhereParamValue = whereValue,
                WhereString = whereString
            });
        }

        /// <summary>
        /// 新增格式化条件
        /// </summary>
        /// <param name="whereString"></param>
        /// <param name="paramDic"></param>
        protected void AddWhere(string whereString, params (string, object)[] paramDic)
        {
            if (string.IsNullOrWhiteSpace(whereString) && paramDic.Length <= 0) return;
            if (!string.IsNullOrWhiteSpace(whereString)) AddWhere(whereString);
            foreach (var kv in paramDic)
            {
                AddWhere(string.Empty, kv.Item1, kv.Item2);
            }
        }

        /// <summary>
        /// 增加固定查询条件
        /// </summary>
        /// <param name="whereString"></param>
        protected void AddWhere(string whereString)
        {
            AddWhere(whereString, string.Empty, null);
        }

        /// <summary>
        /// 新增排序集合
        /// </summary>
        /// <param name="sortString"></param>
        /// <param name="sortType"></param>
        protected void AddSort(string sortString, SortType sortType)
        {
            sortString = sortString.TrimStart();
            var sort = $" {sortString} {sortType}";
            if (!Sorts.Contains(sort))
            {
                Sorts.Add(sort);
            }
        }

        /// <summary>
        /// 清空排序
        /// </summary>
        protected void ClearSort() => Sorts?.Clear();

        /// <summary>
        /// 构建完整查询语句  携带查询条件 排序条件
        /// </summary>
        /// <returns></returns>
        public string BuildSelectSql()
        {
            var sql = GetSelectSql();
            var where = GetWhereString();
            var fullSql = $"{sql} {where}";
            if (Sorts?.Count > 0)
            {
                fullSql += $" order by {string.Join(",", Sorts)}";
            }

            return fullSql;
        }

        /// <summary>
        /// 获取where查询sql
        /// </summary>
        /// <returns></returns>
        protected virtual string GetWhereString()
        {
            InitCondition();
            var sql = string.Join(" ", Wheres.Where(s => !string.IsNullOrWhiteSpace(s.WhereString)).Select(t =>
            {
                var existAnd = t.WhereString.TrimStart().StartsWith("and", true, CultureInfo.CurrentCulture);
                if (existAnd) return t.WhereString;
                return $" and {t.WhereString}";
            }));
            return sql;
        }

        /// <summary>
        /// 
        /// </summary>
        protected void InitCondition()
        {
            if (_isResolveCondition) return;
            lock (this)
            {
                if (!_isResolveCondition)
                {
                    ResolveCondition();
                    ResolveSort();
                    _isResolveCondition = true;
                }
            }
        }

        /// <summary>
        /// 获取where查询条件集合
        /// </summary>
        /// <returns></returns>
        public dynamic GetWhereObject()
        {
            dynamic obj = new ExpandoObject();
            InitCondition();
            var objDic = (IDictionary<string, object>)obj;
            Wheres.Where(w => !string.IsNullOrWhiteSpace(w.WhereParamName))
                .ToList()
                .ForEach(t => { objDic.Add(t.WhereParamName, t.WhereParamValue); });
            return obj;
        }

        // /// <summary>
        // /// 只读库标记
        // /// </summary>
        // public bool QueryWriteDb { get; set; }
    }
}